﻿using System;
using System.Threading;
using Mono.Collections.Generic;

namespace Mono.Cecil.Cil
{
	// Token: 0x0200011F RID: 287
	public sealed class MethodBody
	{
		// Token: 0x170002DC RID: 732
		// (get) Token: 0x06000B25 RID: 2853 RVA: 0x00031BA4 File Offset: 0x0002FDA4
		public MethodDefinition Method
		{
			get
			{
				return this.method;
			}
		}

		// Token: 0x170002DD RID: 733
		// (get) Token: 0x06000B26 RID: 2854 RVA: 0x00031BBC File Offset: 0x0002FDBC
		// (set) Token: 0x06000B27 RID: 2855 RVA: 0x00005F7B File Offset: 0x0000417B
		public int MaxStackSize
		{
			get
			{
				return this.max_stack_size;
			}
			set
			{
				this.max_stack_size = value;
			}
		}

		// Token: 0x170002DE RID: 734
		// (get) Token: 0x06000B28 RID: 2856 RVA: 0x00031BD4 File Offset: 0x0002FDD4
		public int CodeSize
		{
			get
			{
				return this.code_size;
			}
		}

		// Token: 0x170002DF RID: 735
		// (get) Token: 0x06000B29 RID: 2857 RVA: 0x00031BEC File Offset: 0x0002FDEC
		// (set) Token: 0x06000B2A RID: 2858 RVA: 0x00005F85 File Offset: 0x00004185
		public bool InitLocals
		{
			get
			{
				return this.init_locals;
			}
			set
			{
				this.init_locals = value;
			}
		}

		// Token: 0x170002E0 RID: 736
		// (get) Token: 0x06000B2B RID: 2859 RVA: 0x00031C04 File Offset: 0x0002FE04
		// (set) Token: 0x06000B2C RID: 2860 RVA: 0x00005F8F File Offset: 0x0000418F
		public MetadataToken LocalVarToken
		{
			get
			{
				return this.local_var_token;
			}
			set
			{
				this.local_var_token = value;
			}
		}

		// Token: 0x170002E1 RID: 737
		// (get) Token: 0x06000B2D RID: 2861 RVA: 0x00031C1C File Offset: 0x0002FE1C
		public Collection<Instruction> Instructions
		{
			get
			{
				bool flag = this.instructions == null;
				if (flag)
				{
					Interlocked.CompareExchange<Collection<Instruction>>(ref this.instructions, new InstructionCollection(this.method), null);
				}
				return this.instructions;
			}
		}

		// Token: 0x170002E2 RID: 738
		// (get) Token: 0x06000B2E RID: 2862 RVA: 0x00031C5C File Offset: 0x0002FE5C
		public bool HasExceptionHandlers
		{
			get
			{
				return !this.exceptions.IsNullOrEmpty<ExceptionHandler>();
			}
		}

		// Token: 0x170002E3 RID: 739
		// (get) Token: 0x06000B2F RID: 2863 RVA: 0x00031C7C File Offset: 0x0002FE7C
		public Collection<ExceptionHandler> ExceptionHandlers
		{
			get
			{
				bool flag = this.exceptions == null;
				if (flag)
				{
					Interlocked.CompareExchange<Collection<ExceptionHandler>>(ref this.exceptions, new Collection<ExceptionHandler>(), null);
				}
				return this.exceptions;
			}
		}

		// Token: 0x170002E4 RID: 740
		// (get) Token: 0x06000B30 RID: 2864 RVA: 0x00031CB4 File Offset: 0x0002FEB4
		public bool HasVariables
		{
			get
			{
				return !this.variables.IsNullOrEmpty<VariableDefinition>();
			}
		}

		// Token: 0x170002E5 RID: 741
		// (get) Token: 0x06000B31 RID: 2865 RVA: 0x00031CD4 File Offset: 0x0002FED4
		public Collection<VariableDefinition> Variables
		{
			get
			{
				bool flag = this.variables == null;
				if (flag)
				{
					Interlocked.CompareExchange<Collection<VariableDefinition>>(ref this.variables, new VariableDefinitionCollection(this.method), null);
				}
				return this.variables;
			}
		}

		// Token: 0x170002E6 RID: 742
		// (get) Token: 0x06000B32 RID: 2866 RVA: 0x00031D14 File Offset: 0x0002FF14
		public ParameterDefinition ThisParameter
		{
			get
			{
				bool flag = this.method == null || this.method.DeclaringType == null;
				if (flag)
				{
					throw new NotSupportedException();
				}
				bool flag2 = !this.method.HasThis;
				ParameterDefinition result;
				if (flag2)
				{
					result = null;
				}
				else
				{
					bool flag3 = this.this_parameter == null;
					if (flag3)
					{
						Interlocked.CompareExchange<ParameterDefinition>(ref this.this_parameter, MethodBody.CreateThisParameter(this.method), null);
					}
					result = this.this_parameter;
				}
				return result;
			}
		}

		// Token: 0x06000B33 RID: 2867 RVA: 0x00031D8C File Offset: 0x0002FF8C
		private static ParameterDefinition CreateThisParameter(MethodDefinition method)
		{
			TypeReference typeReference = method.DeclaringType;
			bool hasGenericParameters = typeReference.HasGenericParameters;
			if (hasGenericParameters)
			{
				GenericInstanceType genericInstanceType = new GenericInstanceType(typeReference, typeReference.GenericParameters.Count);
				for (int i = 0; i < typeReference.GenericParameters.Count; i++)
				{
					genericInstanceType.GenericArguments.Add(typeReference.GenericParameters[i]);
				}
				typeReference = genericInstanceType;
			}
			bool flag = typeReference.IsValueType || typeReference.IsPrimitive;
			if (flag)
			{
				typeReference = new ByReferenceType(typeReference);
			}
			return new ParameterDefinition(typeReference, method);
		}

		// Token: 0x06000B34 RID: 2868 RVA: 0x00005F99 File Offset: 0x00004199
		public MethodBody(MethodDefinition method)
		{
			this.method = method;
		}

		// Token: 0x06000B35 RID: 2869 RVA: 0x00031E20 File Offset: 0x00030020
		public ILProcessor GetILProcessor()
		{
			return new ILProcessor(this);
		}

		// Token: 0x040005D3 RID: 1491
		internal readonly MethodDefinition method;

		// Token: 0x040005D4 RID: 1492
		internal ParameterDefinition this_parameter;

		// Token: 0x040005D5 RID: 1493
		internal int max_stack_size;

		// Token: 0x040005D6 RID: 1494
		internal int code_size;

		// Token: 0x040005D7 RID: 1495
		internal bool init_locals;

		// Token: 0x040005D8 RID: 1496
		internal MetadataToken local_var_token;

		// Token: 0x040005D9 RID: 1497
		internal Collection<Instruction> instructions;

		// Token: 0x040005DA RID: 1498
		internal Collection<ExceptionHandler> exceptions;

		// Token: 0x040005DB RID: 1499
		internal Collection<VariableDefinition> variables;
	}
}
